package texture;

import game.StitcherStatus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

//C:\Users\shelby.liu\workspace2\M5_V1\assets\minecraft\textures\blocks
public class TextureMap extends AbstractTexture implements TickableTextureObject {
	public String[][] getTextureNames() {
		return StitcherStatus.get().getTextureNames();
	}

	public static final ResourceLocation locationBlocksTexture = new ResourceLocation("textures/atlas/blocks.png");
	private final Map<String, TextureAtlasSprite> mapRegisteredSprites = new HashMap<>();
	private final Map<String, TextureAtlasSprite> mapUploadedSprites = new HashMap<>();
	
	/** 0 = terrain.png, 1 = items.png */
	public final int textureType;
	public final String basePath;

	private final List<TextureAtlasSprite> listAnimatedSprites = new ArrayList<>();
	private final TextureAtlasSprite missingImage = new TextureAtlasSprite("missingno");

	public Stitcher stitcher;

	public TextureMap(int par1, String par2Str) {
		this.textureType = par1;
		this.basePath = par2Str;
		this.registerIcons();
	}

	private void registerIcons() {
		this.mapRegisteredSprites.clear();
		String[][] textureNames = getTextureNames();
		for (int i = 0; i < textureNames.length; i++) {
			String[] row = textureNames[i];
			for (int j = 0; j < row.length; j++) {
				registerIcon(row[j]);
			}
		}
	}

	private void registerIcon(String par1Str) {
		if (par1Str == null) {
			return;
		}

		TextureAtlasSprite object = this.mapRegisteredSprites.get(par1Str);
		if (object != null) {
			return;
		}

		if (this.textureType == 1) {
			object = new TextureAtlasSprite(par1Str);
		} else {
			object = new TextureAtlasSprite(par1Str);
		}

		this.mapRegisteredSprites.put(par1Str, object);
	}

	public int getTextureType() {
		return textureType;
	}

	public void loadTexture(ResourceManager par1ResourceManager) {
		this.initMissingImage();

		int maxTexSize = GLReferenceTexture.glMaximumTextureSize();
		this.stitcher = new StitcherDynamic(maxTexSize, maxTexSize, true);
		this.mapUploadedSprites.clear();
		this.listAnimatedSprites.clear();

		// Iterator<Entry<String, TextureAtlasSprite>> iterator = this.mapRegisteredSprites.entrySet().iterator();
		// while (iterator.hasNext()) {
		String[][] textureNames = getTextureNames();
		for (int i = 0; i < textureNames.length; i++) {
			String[] row = textureNames[i];
			for (int j = 0; j < row.length; j++) {
				String key = row[j];

				if (key == null || key.trim().length() <= 0) {
					continue;
				}

				// Entry<String, TextureAtlasSprite> entry = mapRegisteredSprites.get(row[j]);
				ResourceLocation resourcelocation = new ResourceLocation(key);
				TextureAtlasSprite textureatlassprite = mapRegisteredSprites.get(key);
				String recourcePath = String.format("%s/%s%s", new Object[] { this.basePath, resourcelocation.getResourcePath(), ".png" });

				// full location with the base path and file name extension appended
				ResourceLocation resourcelocation1 = new ResourceLocation(resourcelocation.getResourceDomain(), recourcePath);
				try {
					if (!textureatlassprite.load(par1ResourceManager, resourcelocation1)) {
						continue;
					}
				} catch (RuntimeException runtimeexception) {
					System.out.println(String.format("Unable to parse animation metadata from %s: %s",
							new Object[] { resourcelocation1, runtimeexception.getMessage() }));
					continue;
				} catch (IOException ioexception) {
					System.out.println("Using missing texture, unable to load: " + resourcelocation1);
					continue;
				}
				stitcher.addSprite(textureatlassprite);
			}
		}

		stitcher.addSprite(this.missingImage);
		stitcher.doStitch();

		TextureUtil.allocateTexture(this.getGlTextureId(), stitcher.getCurrentWidth(), stitcher.getCurrentHeight());
		HashMap<String, TextureAtlasSprite> hashmap = new HashMap<>(this.mapRegisteredSprites);
		Iterator<TextureAtlasSprite> iterator1 = stitcher.getStichSlots().iterator();
		TextureAtlasSprite textureatlassprite1;

		while (iterator1.hasNext()) {
			textureatlassprite1 = iterator1.next();
			String s = textureatlassprite1.getIconName();
			hashmap.remove(s);
			this.mapUploadedSprites.put(s, textureatlassprite1);

			try {
				TextureUtil.uploadTextureSub(textureatlassprite1.getFrameTextureData(0), textureatlassprite1.getIconWidth(),
						textureatlassprite1.getIconHeight(), textureatlassprite1.getOriginX(), textureatlassprite1.getOriginY(), false, false);
			} catch (Throwable throwable) {
				throwable.printStackTrace();
			}

			if (textureatlassprite1.hasAnimationMetadata()) {
				this.listAnimatedSprites.add(textureatlassprite1);
			} else {
				textureatlassprite1.clearFramesTextureData();
			}
		}

		iterator1 = hashmap.values().iterator();

		while (iterator1.hasNext()) {
			textureatlassprite1 = (TextureAtlasSprite) iterator1.next();
			textureatlassprite1.copyFrom(this.missingImage);
		}
	}

	private void initMissingImage() {
		ArrayList<int[]> list = new ArrayList<>();
		Collections.addAll(list, new int[][] { TextureUtil.missingTextureData });
		this.missingImage.setFramesTextureData(list);
		this.missingImage.setIconWidth(16);
		this.missingImage.setIconHeight(16);
	}

	public void tick() {
		this.updateAnimations();
	}

	private void updateAnimations() {
		TextureUtil.bindTexture(this.getGlTextureId());
		for (TextureAtlasSprite item : listAnimatedSprites) {
			item.updateAnimation();
		}
	}
}
